package cn.exrick.xboot.common.qywxCode.Security;

import cn.exrick.xboot.common.constant.CommonConstant;
import cn.exrick.xboot.common.jiuqiCommon.callAPIUtil.CallApiUtil;
import cn.exrick.xboot.common.utils.SpringUtils;
import cn.exrick.xboot.common.utils.jiuqi.utils.EncryptUtil;
import cn.exrick.xboot.modules.base.dao.mapper.UserRoleMapper;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.findUserByUsername;
import cn.exrick.xboot.modules.base.serviceimpl.UserServiceImpl;
import cn.exrick.xboot.modules.callApi.CallApi;
import cn.exrick.xboot.modules.portalConfig.entity.PortalConfig;
import cn.exrick.xboot.modules.portalConfig.service.IPortalConfigService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 短信登录的鉴权过滤器，模仿 UsernamePasswordAuthenticationFilter 实现
 */
public class SmsCodeAuthenticationFilter
        extends AbstractAuthenticationProcessingFilter {
    /**
     * form表单中的用户名
     */

    //相当于登录时的用户名
    private String username = CommonConstant.SPRING_SECURITY_FORM_USERNAME;

    //密码
    private String pwd = CommonConstant.SPRING_SECURITY_FORM_PWD;

    //验证码
    private String captchaId = CommonConstant.SPRING_SECURITY_FORM_CAPTCHA_ID;

    //登陆方式标识
    private String loginStyle = CommonConstant.SPRING_SECURITY_FORM_LOGIN_STYLE;
    @Autowired
    private CallApi callApi;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private findUserByUsername userService;
    @Autowired
    private IPortalConfigService iPortalConfigService;
    @Autowired
    private UserServiceImpl userServiceImpl;

    /**
     * 是否仅 POST 方式
     */
    private boolean postOnly = true;
    @Autowired
    UserRoleMapper userRoleMapper;

    public static SmsCodeAuthenticationFilter smsCodeAuthenticationFilter;

    public SmsCodeAuthenticationFilter() {
        // 短信登录的请求 post 方式的 /sms/login
        super(new AntPathRequestMatcher("/xboot/login/code", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        /**获取登录表单的用户名与密码*/
        String username = (String) obtainUsername(request);
        String pwd = (String) obtainPwd(request);

        JSONObject jsonObject = new JSONObject();
        JSONObject resultJson = new JSONObject();
       /* Map<Object, String> map = new HashMap();

        *//**校验用户名是身份证号，还是手机号*//*
        IsPhoneNum isPhoneNum = new IsPhoneNum();
        Boolean isPhone = isPhoneNum.isMobile(username);

        try {
            if (isPhone) {
                map.put("cellphone",
                        EncryptUtil.DESencode(username, CommonConstant.ENCRYPT_KEY));
                map.put("userCode", "");
            } else {
                map.put("cellphone", "");
                map.put("userCode",
                        EncryptUtil.DESencode(username, CommonConstant.ENCRYPT_KEY));
            }

            map.put("sender", "PORTAL");

            map.put("pwd",
                    EncryptUtil.DESencode(pwd, CommonConstant.ENCRYPT_KEY));
        } catch (Exception e) {
            logger.error("加密工具类报异常：{}" + e.getMessage());
        }

        jsonObject.put("data", map);*/


        if (iPortalConfigService == null) {
            iPortalConfigService = (IPortalConfigService) SpringUtils.getBean("IPortalConfigServiceImpl");
        }

        if (userService == null) {
            userService = (findUserByUsername) SpringUtils.getBean("findUserByUsernameImpl");
        }

        User user = userService.findByUsername(username);

        if (user != null) {

            /*throw new AuthenticationServiceException("登录验证，子系统返回体为空");*/
            SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(user);
            // Allow subclasses to set the "details" property（允许子类设置detail属性）
            setDetails(request, authRequest);

            //调用Manager
            return this.getAuthenticationManager().authenticate(authRequest);
        }

        try {
            PortalConfig portalConfig = iPortalConfigService.selectPortalConfigByKey("validateUser");
            resultJson = CallApiUtil.doPost(jsonObject, portalConfig.getValue());
        } catch (Exception e) {
            logger.error("调用出错" + e.getMessage());
        }

        //校验未通过
        String flag = resultJson.getString("flag");

        String str = "0";

        if ((flag != null) && flag.equals(str)) {
            user = userService.findByUsername(username);

            if (user != null) {
                SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(user);
                // Allow subclasses to set the "details" property（允许子类设置detail属性）
                setDetails(request, authRequest);
                //调用Manager
                return this.getAuthenticationManager().authenticate(authRequest);
            } else {
                throw new AuthenticationServiceException(resultJson.getString("message"));
            }
        } else {
            String idcard = resultJson.getJSONObject("data").getString("userCode");
            //默认通过，获取的身份证号
            logger.info("返回的身份证号：" + idcard);

            User u = new User();
            u.setUsername(username);
            u.setType(0);
            u.setPassword(pwd);
            u.setIdcard(idcard);

            try {
                u.setIdcardEncryption(EncryptUtil.DESencode(idcard,
                        CommonConstant.ENCRYPT_KEY));
            } catch (Exception e) {
                logger.error("加密工具类报异常：{}" + e.getMessage());
            }

            SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(u);
            // Allow subclasses to set the "details" property（允许子类设置detail属性）
            setDetails(request, authRequest);

            //调用Manager
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }

    //获得登录时的密码
    private String obtainPwd(HttpServletRequest request) {
        return request.getParameter(pwd);
    }

    //获得登录时的用户名
    public String obtainUsername(HttpServletRequest request) {
        return request.getParameter(username);
    }

    public void setDetails(HttpServletRequest request,
                           SmsCodeAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    public String getusername() {
        return username;
    }

    public void setusername(String username) {
        Assert.hasText(username, "Mobile parameter must not be empty or null");
        this.username = username;
    }

    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }
}
